package com.audaque.springboot.foshanupload.security.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.audaque.springboot.foshanupload.authcore.constants.AuthConst;
import com.audaque.springboot.foshanupload.authcore.model.currentUser.TransmittableThreadLocalCurrentUser;
import com.audaque.springboot.foshanupload.security.component.MyMd5PasswordEncoder;
import com.audaque.springboot.foshanupload.security.model.MyGrantedAuthority;
import com.audaque.springboot.foshanupload.security.model.MyUserDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @author zgb
 * @desc 作为数据库代理
 * @date 2022-08-05 17:35:30
 */
@Service
public class MyUserDetailService implements UserDetailsService {
    @Autowired
    private MyMd5PasswordEncoder myMd5PasswordEncoder;

    @Value("${db.tenantId}")
    private String tenantId;

    /**
     * 根据用户名生成认证令牌：UsernamePasswordAuthenticationToken(myUserDetail, password, authorities);
     *
     * @param username
     * @return
     */
    public UsernamePasswordAuthenticationToken getUsernamePasswordAuthenticationTokenByByUsername(String username) {
        //数据库里
        MyUserDetail myUserDetail = (MyUserDetail) this.loadUserByUsername(username);

        if (myUserDetail == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }

        String password = myUserDetail.getPassword();
        Set<MyGrantedAuthority> authorities = myUserDetail.getAuthorities();
        //myUserDetail作为身份信息
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(myUserDetail, password, authorities);
        return usernamePasswordAuthenticationToken;

    }

    /**
     * 根据用户名查用户信息
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //根据用户名查用户是否存在，不存在则抛异常
        TransmittableThreadLocalCurrentUser transmittableThreadLocalCurrentUser = new TransmittableThreadLocalCurrentUser();
        transmittableThreadLocalCurrentUser.setId(AuthConst.USER_ID);
        transmittableThreadLocalCurrentUser.setTenantId(tenantId);
        transmittableThreadLocalCurrentUser.setUsername(AuthConst.USERNAME);
        transmittableThreadLocalCurrentUser.setPassword(myMd5PasswordEncoder.encode(AuthConst.PASSWORD));
        MyUserDetail myUserDetail = BeanUtil.toBean(transmittableThreadLocalCurrentUser, MyUserDetail.class);
        //根据用户名查用户权限
        //用户的权限
        Set<MyGrantedAuthority> authorities = new LinkedHashSet<>();
        MyGrantedAuthority myGrantedAuthority = new MyGrantedAuthority();
        //角色其实相当于一个"ROLE_"+role的资源。
        //添加角色
        myGrantedAuthority.setAuthority("ROLE_test");
        authorities.add(myGrantedAuthority);
        myUserDetail.setAuthorities(authorities);
        myUserDetail.setAccountNonExpired(true).setAccountNonLocked(true).setCredentialsNonExpired(true).setEnabled(true);
        //实例化,返回用户账号密码和权限信息给security使用
        return myUserDetail;
    }
}
